/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.testis.gui.mvc.utilities;

import org.testis.client.TestisApplicationContext;
import org.testis.data.TestStepAbortAll;
import org.testis.data.TestStepResultSynchReciever;
import org.testis.gui.mvc.controller.TestDesignControllerList;
import org.testis.gui.mvc.view.ErrorTextWindow;
import org.testis.logging.LogSenderService;
import org.testis.services.TestStepExecutor;
import org.testis.testdriver.AtofEnumaration.AtofLogLevel;
import org.testis.testdriver.AtofEnumaration.ExecutionInterventionType;
import org.testis.testdriver.Debugger;
import org.testis.testdriver.ExecutionGuidProvider;
import org.testis.testdriver.ExecutionInterface;
import org.testis.testdriver.FailedDebugger;
import org.testis.testdriver.InputNotificationInterface;
import org.testis.testdriver.NotificationSubjectSingleton;
import org.testis.testdriver.Runner;
import org.testis.testdriver.TestPart;
import org.testis.testdriver.TestPlanParser;
import org.testis.threading.Task;
import java.util.LinkedList;
import javax.swing.JFrame;

import org.testis.orm.refinedclasses.TestDesignTreeNode;

/**
 *
 * @author emir
 */
public class TestRunner extends Task implements InputNotificationInterface {

    private TestDesignTreeNode m_node;
    private int m_mode;
    public final Object execute = new Object();
    private ExecutionInterface m_executer;

    public TestRunner(TestDesignTreeNode node,
            int mode, String taskId) {
        super(taskId);
        m_node = node;
        m_mode = mode;
    }

    public static void operationGenerateErrorMessage(String message,
            String title) {

        ErrorTextWindow e = new ErrorTextWindow(new JFrame(), true);

        e.showMessage(message,
                title);
        e.setVisible(true);
    }

    @Override
    public void run() {

        if (!(m_node != null && m_mode >= 0 && m_mode < 3)) {
            return;
        }
        NotificationSubjectSingleton notifysubject =
                NotificationSubjectSingleton.createInstance(false);
        try {
            TestisApplicationContext.initializeForRunner();
            TestPlanParser gh = new TestPlanParser();
            TestPart sample;
            notifysubject.register(this);
            sample = gh.construct(m_node);
            switch (m_mode) {
                case 0:
                    m_executer = new FailedDebugger(sample);
                    break;
                case 1:
                    m_executer = new Debugger(sample);
                    break;
                case 2:
                    m_executer = new Runner(sample);
                    break;
                default:
                    m_executer = new Runner(sample);
            }
            ExecutionGuidProvider.createInstance().generateNewExecId();
            m_executer.setExecutionIntervention(ExecutionInterventionType.Resume);
            TestDesignControllerList.newInstance().getRunningTestSuiteController().
                    operationSetRunning(true);
            m_executer.execute();
        } catch (NullPointerException ex) {
            ex.printStackTrace();
            operationGenerateErrorMessage(ex.getMessage(),
                    "Error in test suite");
        } catch (RuntimeException ex) {
            ex.printStackTrace();
            operationGenerateErrorMessage(ex.getMessage(),
                    "Error in test suite");
        } catch (Exception ex) {
            ex.printStackTrace();
            operationGenerateErrorMessage(ex.getMessage(),
                    "Error in test suite");
        } finally {
            try {
                Thread.sleep(5000);
            } catch (Exception ex) {
            }
            TestisApplicationContext.close();
            notifysubject.unregister(this);
            TestStepExecutor.getResultReciever(true).abortReciever(false);
            TestStepExecutor.getResultReciever(false).abortReciever(false);
            TestStepResultSynchReciever.getInstance().setLastMsgId("");
            TestDesignControllerList.newInstance().getRunningTestSuiteController().
                    operationStop();
        }
    }

    @Override
    public void needInput() {
        TestDesignControllerList.newInstance().getRunningTestSuiteController().
                operationDebuggingBreak(true);
    }

    @Override
    public void execInterventionStateChanged(ExecutionInterventionType val) {
        TestDesignControllerList.newInstance().getRunningTestSuiteController().operationStateChanged(val);
    }

    @Override
    public void notifyLogMessages(String objectDesc,
            AtofLogLevel level,
            String logMsg,
            String guid) {
        LogSenderService.putMessageOnQueue(
                objectDesc,
                org.testis.logging.AtofLogLevel.valueOf(level.toString()),
                logMsg,
                guid);
    }

    @Override
    public void notifyLogHeaderMessages(int designTreeId,
            int designPartType,
            Byte result,
            String parentGuid,
            String name,
            String guid,
            String executionGuid) {
        LogSenderService.putHeaderMessageOnQueue(
                designTreeId,
                designPartType,
                result,
                parentGuid,
                name,
                guid,
                executionGuid);
    }

    public void setExecutionIntervention(ExecutionInterventionType val) {
        if (m_executer != null) {
            m_executer.setExecutionIntervention(val);
            if (val == ExecutionInterventionType.Abort) {
                java.awt.EventQueue.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        TestStepExecutor.getResultReciever(true).abortReciever(true);
                        TestStepExecutor.getResultReciever(false).abortReciever(true);
                        LinkedList<String> messages = new LinkedList<String>();
                        String lstMsgId = TestStepResultSynchReciever.getInstance().getLastMsgId();
                        messages.add(lstMsgId);
                        TestStepAbortAll.getInstance().sendData(messages);
                    }
                });
            }
        }
    }

    @Override
    public void afterExecute() {
    }
}
